package model;

import java.awt.Color;
import java.util.HashMap;

public class SVGColors {

    private final static HashMap<String, String> svgColorNames = 
	new HashMap<String, String>();

    public static Color parseColor(String colorStr) {
	final String HEX = "[0-9a-fA-F]";
	final String HASHCODE3 = "^#" + HEX + HEX + HEX + "$";
	final String HASHCODE6 = "^#" + HEX + HEX + HEX + HEX + HEX + HEX + "$";

	if (colorStr.matches(HASHCODE3)) {
	    // System.err.println("color: #xxx:" + colorStr);
	    colorStr = String.format("#%1$c%1$c%2$c%2$c%3$c%3$c",
		    colorStr.charAt(1), colorStr.charAt(2), colorStr.charAt(3));
	}
	if (colorStr.matches(HASHCODE6)) {
	    // System.err.println("color: #xxxxxx:" + colorStr);
	    return new Color(Integer.parseInt(colorStr.substring(1), 16));
	}

	if (matchesRGB(colorStr)) {
	    return getColorFromRGB(colorStr);
	}

	try {
	    return getColorFromName(colorStr);
	} catch (Exception e) {

	}
	// finally
	// {
	return Color.black;
	// }
    }

    public static boolean matchesRGB(String colorStr) {
	final String WSP = "[ ]*"; // FIXME tabs 'n stuff
	final String COMMA = WSP + "," + WSP;
	final String INTEGER = "\\d{1,3}";
	final String OPT_PC = "[\\%]*";
	final String RGBPATTERN = "[rR][gG][bB]\\(" + WSP + INTEGER + OPT_PC
		+ COMMA + INTEGER + OPT_PC + COMMA + INTEGER + OPT_PC + WSP
		+ "\\)";

	return colorStr.matches(RGBPATTERN);

    }

    public static Color getColorFromRGB(String colorStr)
    // throws exception
    {
	if (matchesRGB(colorStr)) {
	    // get the bits between the brackets
	    String params = colorStr.substring(colorStr.indexOf('(') + 1,
		    colorStr.indexOf(')'));
	    // separate into 3 params
	    String[] tokens = params.split(",");
	    int[] colors = new int[3];
	    int i = 0;
	    for (String t : tokens) {
		// System.out.println("token: " + t);
		t = t.trim();
		if (t.endsWith("%")) {
		    // strip off the % and convert to int
		    colors[i] = 255 * Integer.parseInt(t.substring(0,
			    t.indexOf('%'))) / 100;
		} else
		    // its number 0 - 255
		    colors[i] = Integer.parseInt(t);

		// sanitise values TODO throw exception??
		if (colors[i] > 255)
		    colors[i] = 255;
		i++;
	    }

	    colorStr = String.format("rgb(%d,%d,%d)", colors[0], colors[1],
		    colors[2]);

	    return new Color(colors[0], colors[1], colors[2]);
	}
	// else throw exception

	return Color.black; // shut up eclipse - del if exception added
    }

    public static Color getColorFromName(String name) {
	if (name.equals("none")) {
	    return null;
	}
	String hashcode = svgColorNames.get(name);
	if (hashcode == null) {
	    System.err.println("Parsing colorname failed: " + name);
	    return new Color(0);
	    // TODO throw exception?
	}

	return new Color(Integer.parseInt(hashcode, 16));
    }

    public static void main(String[] args) {
	String[] testColorStrings = { "aqua", "darkgoldenrod",
		"mediumturquoise", "maroon", "salmon", "tan", "whitesmoke",
		"foo", "#0f0", "#667788", "rgb(1,2,255)", "rgb( 100%, 1%, 0%)",
		"rgb(25%,50%,75%)", "rgb( 100, 1%, 22%)", "rgb(100.0%,0.0,999.9)",
		"rgb( 999, -1, 23)", "none" };

	for (String colorStr : testColorStrings)
	    System.out.printf("%-38s was created by parsing %s\n",
		    parseColor(colorStr).toString(), colorStr);

    }

    static {
	svgColorNames.put("aliceblue", "f0f8ff");
	svgColorNames.put("antiquewhite", "faebd7");
	svgColorNames.put("aqua", "00ffff");
	svgColorNames.put("aquamarine", "7fffd4");
	svgColorNames.put("azure", "f0ffff");
	svgColorNames.put("beige", "f5f5dc");
	svgColorNames.put("bisque", "ffe4c4");
	svgColorNames.put("black", "000000");
	svgColorNames.put("blanchedalmond", "ffebcd");
	svgColorNames.put("blue", "0000ff");
	svgColorNames.put("blueviolet", "8a2be2");
	svgColorNames.put("brown", "a52a2a");
	svgColorNames.put("burlywood", "deb887");
	svgColorNames.put("cadetblue", "5f9ea0");
	svgColorNames.put("chartreuse", "7fff00");
	svgColorNames.put("chocolate", "d2691e");
	svgColorNames.put("coral", "ff7f50");
	svgColorNames.put("cornflowerblue", "6495ed");
	svgColorNames.put("cornsilk", "fff8dc");
	svgColorNames.put("crimson", "dc143c");
	svgColorNames.put("cyan", "00ffff");
	svgColorNames.put("darkblue", "00008b");
	svgColorNames.put("darkcyan", "008b8b");
	svgColorNames.put("darkgoldenrod", "b8860b");
	svgColorNames.put("darkgray", "a9a9a9");
	svgColorNames.put("darkgreen", "006400");
	svgColorNames.put("darkgrey", "a9a9a9");
	svgColorNames.put("darkkhaki", "bdb76b");
	svgColorNames.put("darkmagenta", "8b008b");
	svgColorNames.put("darkolivegreen", "556b2f");
	svgColorNames.put("darkorange", "ff8c00");
	svgColorNames.put("darkorchid", "9932cc");
	svgColorNames.put("darkred", "8b0000");
	svgColorNames.put("darksalmon", "e9967a");
	svgColorNames.put("darkseagreen", "8fbc8f");
	svgColorNames.put("darkslateblue", "483d8b");
	svgColorNames.put("darkslategray", "2f4f4f");
	svgColorNames.put("darkslategrey", "2f4f4f");
	svgColorNames.put("darkturquoise", "00ced1");
	svgColorNames.put("darkviolet", "9400d3");
	svgColorNames.put("deeppink", "ff1493");
	svgColorNames.put("deepskyblue", "00bfff");
	svgColorNames.put("dimgray", "696969");
	svgColorNames.put("dimgrey", "696969");
	svgColorNames.put("dodgerblue", "1e90ff");
	svgColorNames.put("firebrick", "b22222");
	svgColorNames.put("floralwhite", "fffaf0");
	svgColorNames.put("forestgreen", "228b22");
	svgColorNames.put("fuchsia", "ff00ff");
	svgColorNames.put("gainsboro", "dcdcdc");
	svgColorNames.put("ghostwhite", "f8f8ff");
	svgColorNames.put("gold", "ffd700");
	svgColorNames.put("goldenrod", "daa520");
	svgColorNames.put("gray", "808080");
	svgColorNames.put("green", "008000");
	svgColorNames.put("greenyellow", "adff2f");
	svgColorNames.put("grey", "808080");
	svgColorNames.put("honeydew", "f0fff0");
	svgColorNames.put("hotpink", "ff69b4");
	svgColorNames.put("indianred", "cd5c5c");
	svgColorNames.put("indigo", "4b0082");
	svgColorNames.put("ivory", "fffff0");
	svgColorNames.put("khaki", "f0e68c");
	svgColorNames.put("lavender", "e6e6fa");
	svgColorNames.put("lavenderblush", "fff0f5");
	svgColorNames.put("lawngreen", "7cfc00");
	svgColorNames.put("lemonchiffon", "fffacd");
	svgColorNames.put("lightblue", "add8e6");
	svgColorNames.put("lightcoral", "f08080");
	svgColorNames.put("lightcyan", "e0ffff");
	svgColorNames.put("lightgoldenrodyellow", "fafad2");
	svgColorNames.put("lightgray", "d3d3d3");
	svgColorNames.put("lightgreen", "90ee90");
	svgColorNames.put("lightgrey", "d3d3d3");
	svgColorNames.put("lightpink", "ffb6c1");
	svgColorNames.put("lightsalmon", "ffa07a");
	svgColorNames.put("lightseagreen", "20b2aa");
	svgColorNames.put("lightskyblue", "87cefa");
	svgColorNames.put("lightslategray", "778899");
	svgColorNames.put("lightslategrey", "778899");
	svgColorNames.put("lightsteelblue", "b0c4de");
	svgColorNames.put("lightyellow", "ffffe0");
	svgColorNames.put("lime", "00ff00");
	svgColorNames.put("limegreen", "32cd32");
	svgColorNames.put("linen", "faf0e6");
	svgColorNames.put("magenta", "ff00ff");
	svgColorNames.put("maroon", "800000");
	svgColorNames.put("mediumaquamarine", "66cdaa");
	svgColorNames.put("mediumblue", "0000cd");
	svgColorNames.put("mediumorchid", "ba55d3");
	svgColorNames.put("mediumpurple", "9370db");
	svgColorNames.put("mediumseagreen", "3cb371");
	svgColorNames.put("mediumslateblue", "7b68ee");
	svgColorNames.put("mediumspringgreen", "00fa9a");
	svgColorNames.put("mediumturquoise", "48d1cc");
	svgColorNames.put("mediumvioletred", "c71585");
	svgColorNames.put("midnightblue", "191970");
	svgColorNames.put("mintcream", "f5fffa");
	svgColorNames.put("mistyrose", "ffe4e1");
	svgColorNames.put("moccasin", "ffe4b5");
	svgColorNames.put("navajowhite", "ffdead");
	svgColorNames.put("navy", "000080");
	svgColorNames.put("oldlace", "fdf5e6");
	svgColorNames.put("olive", "808000");
	svgColorNames.put("olivedrab", "6b8e23");
	svgColorNames.put("orange", "ffa500");
	svgColorNames.put("orangered", "ff4500");
	svgColorNames.put("orchid", "da70d6");
	svgColorNames.put("palegoldenrod", "eee8aa");
	svgColorNames.put("palegreen", "98fb98");
	svgColorNames.put("paleturquoise", "afeeee");
	svgColorNames.put("palevioletred", "db7093");
	svgColorNames.put("papayawhip", "ffefd5");
	svgColorNames.put("peachpuff", "ffdab9");
	svgColorNames.put("peru", "cd853f");
	svgColorNames.put("pink", "ffc0cb");
	svgColorNames.put("plum", "dda0dd");
	svgColorNames.put("powderblue", "b0e0e6");
	svgColorNames.put("purple", "800080");
	svgColorNames.put("red", "ff0000");
	svgColorNames.put("rosybrown", "bc8f8f");
	svgColorNames.put("royalblue", "4169e1");
	svgColorNames.put("saddlebrown", "8b4513");
	svgColorNames.put("salmon", "fa8072");
	svgColorNames.put("sandybrown", "f4a460");
	svgColorNames.put("seagreen", "2e8b57");
	svgColorNames.put("seashell", "fff5ee");
	svgColorNames.put("sienna", "a0522d");
	svgColorNames.put("silver", "c0c0c0");
	svgColorNames.put("skyblue", "87ceeb");
	svgColorNames.put("slateblue", "6a5acd");
	svgColorNames.put("slategray", "708090");
	svgColorNames.put("slategrey", "708090");
	svgColorNames.put("snow", "fffafa");
	svgColorNames.put("springgreen", "00ff7f");
	svgColorNames.put("steelblue", "4682b4");
	svgColorNames.put("tan", "d2b48c");
	svgColorNames.put("teal", "008080");
	svgColorNames.put("thistle", "d8bfd8");
	svgColorNames.put("tomato", "ff6347");
	svgColorNames.put("turquoise", "40e0d0");
	svgColorNames.put("violet", "ee82ee");
	svgColorNames.put("wheat", "f5deb3");
	svgColorNames.put("white", "ffffff");
	svgColorNames.put("whitesmoke", "f5f5f5");
	svgColorNames.put("yellow", "ffff00");
	svgColorNames.put("yellowgreen", "9acd32");
    }
}